package org.purpleaf.ext.loader;

import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Objects;

/**
 * 扩展类加载器
 * @author 紫叶工作室
 */
public class ExtClassLoader extends URLClassLoader {

    public static final String EXTS_FILE_PATH_NAME = "exts";

    public static final String EXTS_FILE_TYPE_NAME = ".jar";

    public ExtClassLoader() {
        this(new URL[0], ExtClassLoader.getSystemClassLoader());
    }

    private ExtClassLoader(@NonNull URL[] urls, @NonNull ClassLoader parent) {
        super(urls, parent);
        File extsFile = new File(EXTS_FILE_PATH_NAME);
        if (!extsFile.exists()) {
            if (!extsFile.mkdirs()) {
                throw new RuntimeException("Failed to make '" +
                        extsFile.getAbsolutePath() + "' directory.");
            }
        }
        File[] fileList = extsFile.listFiles();
        if (Objects.isNull(fileList)) {
            throw new RuntimeException("Failed to scan '" +
                    extsFile.getAbsolutePath() + "' directory.");
        }
        for (File file : fileList) {
            if (file.isFile()) {
                String name = file.getName();
                if (name.contains(".")) {
                    int last = name.lastIndexOf(".");
                    if (last != -1) {
                        String type = name.substring(last);
                        if (type.equalsIgnoreCase(EXTS_FILE_TYPE_NAME)) {
                            try {
                                addURL(file.toURI()
                                        .toURL());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    @Nullable
    @Override
    public Class<?> loadClass(@NonNull String name) {
        try {
            return super.loadClass(name);
        } catch (Exception e) {
            return null;
        }
    }

    @Nullable
    @Override
    public Enumeration<URL> getResources(@NonNull String name) {
        try {
            return super.getResources(name);
        } catch (Exception e) {
            return null;
        }
    }
}